Московский Авиационный Институт

(Технический университет)













Курсовой проект












Студент: Кузнецов А.В. 06-321
























Москва 2003

Table of Contents

2

Модули 3

error.h 3

error.c 3

types.h 3

parse.h 3

parse.c 3

select.h 4

select.c 5

show.h 8

show.c 8

sort.h 9

sort.c 9

stdio.h 17

stdio.c 17

stdlib.h 18

stdlib.c 18

Stage.c 20


Модули

  1. Разбора ввода пользователя

  2. Проверка параметров

  3. Получение данных из файлов

  4. Сортировка

  5. Вывод

  6. Ошибок


error.h

// установка текста ошибки

void seterror(const char*);

// получить текст ошибки

const char* geterror();

error.c

#include "error.h"

#include "stdlib.h"


char m_errortext[256]={0};


void seterror(const char* p)

{

_strcpy(m_errortext,p);

}


const char* geterror()

{

return m_errortext;

}

types.h

#ifndef __TYPES_H

#define __TYPES_H


typedef char fieldname[64];

typedef char tablename[64];

typedef char field[512];


#endif

parse.h

// parse - функция разберает входную строчку

// fieldname *flds - список полей

// int fldmax - максимальное количество полей

// tablename* tbls - входные такблицы(файлы)

// int tblmax - максимальное количество таблиц

// fieldname *ord - поле сортировки

// const char* cmdline - строчка для разбора

int parse(fieldname *flds,int fldmax,tablename* tbls,int tblmax,fieldname *ord,const char* cmdline);

parse.c

#include "types.h"

#include "parse.h"

#include "stdlib.h"

#include "error.h"


#define ISLETTER(x) ((x>='a'&&x<='z')||(x>='A'&&x<='Z'))

#define ISNUMBER(x) (x>='0'&&x<='9')

#define ISLETNUM(x) (ISLETTER(x)||ISNUMBER(x)||x=='*'||x=='_'||x=='.')


// получает целое слово


const char* getnexttok(const char* cmdline,char *buf)

{

if(cmdline==0||*cmdline==0)

return 0;

while(!ISLETNUM(*cmdline))

cmdline++;

while(ISLETNUM(*cmdline))

*buf++=*cmdline++;

*buf=0;

return cmdline;

}


int parse(fieldname *flds,int fldsmax,tablename *tbls,int tblmax,fieldname *ord,const char* cmdline)

{

char buf[50];


cmdline=getnexttok(cmdline,buf);

if(_streq(buf,"select")==0)

{

seterror("cmd line must begin from 'select'");

return 0;

}


while((cmdline=getnexttok(cmdline,buf))!=0&&!_streq(buf,"from"))

{

if(fldsmax--==0)

{

seterror("flelds overflow");

return 0;

}

_strcpy(*flds++,buf);

}

while((cmdline=getnexttok(cmdline,buf))!=0&&!_streq(buf,"order"))

{

if(tblmax--==0)

{

seterror("tables overflow");

return 0;

}

_strcpy(*tbls++,buf);

}

if((cmdline=getnexttok(cmdline,buf))==0||!_streq(buf,"by"))

{

seterror("order by not found");

return 0;

}

if((cmdline=getnexttok(cmdline,buf))!=0)

{

_strcpy(*ord,buf);

}

return 1;

}

select.h

// модуль работы с базой данных (файлами)


// select - производит запрос по полям (flds) из указанных таблиц (tbl) (файлов)

// и помещает результат в data, ограниченный datamax

int select(int *selectfieldsidx,int selectfieldsidxcount,tablename *tbl,field *data,int datamax);


// нормализует параметры для передачи их в функции запроса


int normalizeparams(fieldname* selectfields,fieldname* orderfield,tablename *tbl,int* selectfieldsidx,int *selectfieldscount,int *orderfieldidx);

select.c

#include "types.h"

#include "select.h"

#include "error.h"

#include "stdlib.h"


#include "stdio.h"


// assist {


// чтение одного елемента из входного файла

// return:

// 1 чтение успешно

// 0 чтение строчку заверешено

// -1 конец файла


int readline(char* p,int max,FILE* f)

{

int c;

while((c=fgetc(f))!=EOF)

{

if(c==0xa)

{

*p=0;

return 0;

}

if(c==';')

{

*p=0;

return 1;

}

if(!--max)

{

*p=0;

return 1;

}

*p++=c;

}

return -1;

}


// чтение заголовков из файла


int readheaders(FILE* f,fieldname* headers,int headersmax)

{

int i=0;

int read=1;

while(read==1)

{

read=readline(*headers++,sizeof(fieldname),f);

if(i>=headersmax)

{

seterror("max headers reach");

return -1;

}

i++;

}

if(i==0)

{

seterror("no headers read");

return -1;

}

return i;

}


// чтение поля из файла


int readfield(field* p,FILE* f)

{

return readline((char*)p,sizeof(field),f);

}


// чтение из файла всех полей.

// selectfieldsidx - индексы полей

// selectfieldsidxcount - количество полей

// tbl - имя таблицы

// *data выходные данные (они содержаться в файле)

// datamax - объем буфера


int readfile(int *selectfieldsidx,int selectfieldsidxcount,tablename *tbl,field *data,int datamax)

{

int dataleft=datamax;


FILE *f=fopen(*tbl,"r");

fieldname headers[32]={0};

int headersmax=sizeof(headers)/sizeof(fieldname);

int i;

field fld;


if(f==0)

{

seterror("can't open input file");

return -1;

}


if(readheaders(f,headers,headersmax)==-1)

return -1;


while(!feof(f))

{//читаю все строчки

int read=1;

i=0;

while(read==1)

{

//читаю пока строка содержит ячейки

read=readfield(&fld,f);

if(findinnumarray(selectfieldsidx,selectfieldsidxcount,i)!=-1)

{//нужно добавить в считанные данные

if(dataleft--==0)

{

seterror("data overflow");

return -1;

}

_strcpy(*data++,fld);

}

i++;

}

}


fclose(f);


return datamax-dataleft;

}


// } assist


int select(int *selectfieldsidx,int selectfieldsidxcount,tablename *tbl,field *data,int datamax)

{

int total=0;

while(**tbl)

{

int read=readfile(selectfieldsidx,selectfieldsidxcount,tbl,data,datamax);

if(read==-1)

return -1;

data+=read;

datamax-=read;

total+=read;

tbl++;

}

return total;

}


int normalizeparams(fieldname* selectfields,fieldname* orderfield,tablename *tbl,int* selectfieldsidx,int *selectfieldscount,int *orderfieldidx)

{

int ret=1;

FILE *f=0;

int i;

int star=0;

*orderfieldidx=-1;

{

fieldname* fld=selectfields;


i=0;

while(**fld!=0)

{

if(_streq(*fld,"*"))

{

star++;

}

i++;

fld++;

}

if(star>1)

{

seterror("more that one '*'");

goto error;

}

if(star==1&&i!=1)

{

seterror("have '*' with other fields");

goto error;

}

}


while(**tbl!=0)

{

fieldname headers[32]={0};

int headersmax=sizeof(headers)/sizeof(fieldname);

int headerscount;


f=fopen(*tbl,"r");


if(f==0)

{

seterror("can't open input file");

goto error;

}


if((headerscount=readheaders(f,headers,headersmax))==-1)

goto error;


if(star==0)

{

*selectfieldscount=0;

for(i=0;i<headerscount;i++)

{

int *selectfieldsidx_itr=selectfieldsidx;

fieldname* fld=selectfields;

while(**fld!=0)

{

if(_stringformatcmp(headers[i],*fld)==0)

{

*selectfieldsidx_itr++=i;

(*selectfieldscount)++;

}

fld++;

}

}

}else

{

int *selectfieldsidx_itr=selectfieldsidx;

*selectfieldscount=headerscount;


for(i=0;i<headerscount;i++)

{

*selectfieldsidx_itr++=i;

}

}


for(i=0;i<*selectfieldscount;i++)

{

if(_stringformatcmp(headers[selectfieldsidx[i]],*orderfield)==0)

*orderfieldidx=selectfieldsidx[i];

}


fclose(f);

tbl++;

}


if(*orderfieldidx==-1)

{

seterror("order field not found");

goto error;

}


goto exit;

error:

ret=0;

exit:

if(f!=0)

fclose(f);

return ret;

}

show.h

// показывает результат операции, записывая его ввыходной файл

int show(field *data, int *selectfieldsidx, int selectfieldscount,int orderfieldidx,const char* filename);

show.c

#include "types.h"

#include "show.h"


#include "stdio.h"

#include "stdlib.h"


int show(field *data, int *selectfieldsidx, int selectfieldscount,int orderfieldidx, const char* filename)

{

int keyfieldnum=findinnumarray(selectfieldsidx,selectfieldscount,orderfieldidx);

FILE *f=fopen(filename,"w");


/*

while(**flds2!=0)

{

fwritestring(f,*flds2++);

fwritestring(f,";");

}

fwritestring(f,"\n");

*/


while(**data!=0)

{

int i;

fwritestring(f,*(data+keyfieldnum));

fwritestring(f," -> ;");

for(i=0;i<selectfieldscount;i++)

{

fwritestring(f,*data++);

fwritestring(f,";");

}

fwritestring(f,"\n");

}

fclose(f);

return 1;

}

sort.h

// data - что сортируем

// flds - заголовки. по их полчисеству определяю размер столбцов

// orderfield - заголовок сортировки

int sort(field *data,int datasize,int *selectfieldsidx,int selectfieldscount,int orderfieldidx);

sort.c

#include "types.h"

#include "sort.h"

#include "stdlib.h"


// количество лент

#define T 6


// физическое устройство

int* tape[T];

// головка записи\четния

int* tape_ptr[T];


// запись на ленту


void tapewrite(int tapeindex, int what)

{

*tape_ptr[tapeindex]=what;

tape_ptr[tapeindex]++;

}


// чтение с ленты


int taperead(int tapeindex)

{

return *tape_ptr[tapeindex]++;

}


// переметывает линту


void tapeinit(int tapeindex)

{

tape_ptr[tapeindex]=tape[tapeindex];

}


// перематывает ленты


void tapesinit()

{

int i=T;

for(i=0;i<T;i++)

tapeinit(i);

}


// подает питание на устройство, вставляет лену указанной длинны


void tapescreate(int datasize)

{

int i;

for(i=0;i<T;i++)

{

tape[i]=(int*)malloc(datasize*sizeof(int));

tape_ptr[i]=tape[i];

}

}


// выключает устройство


void tapesclose()

{

int i;

for(i=0;i<T;i++)

free(tape[i]);

}


// функция сравнения полей

// результат указывает на наименьшее поле (-1 0 1)

int compare(field* data, int idx1,int idx2)

{

const char* p1,*p2;


if(idx1==-1&&idx2==-1)

return 0;

if(idx1==-1)

return 1;

if(idx2==-1)

return -1;

if(idx1==idx2)

return 0;


p1=data[idx1];

p2=data[idx2];

if(*p1=='"'&&*p2=='"')

{// сравнение строк

return _strcmp(p1,p2);

}else if(*p1!='"'&&*p1!='"')

{// сравнение числе

double fp1=atof(p1),fp2=atof(p2);

if(fp1==fp2)

return 0;

return fp1<fp2?-1:1;

}else

{// операция не определена, идет сравнение строки с числом

return 0;

}

}


// сравнивает поля


void sortfields(field* data,int* idx,int datacount)

{

int i,ii;

restart:

for(i=0;i<datacount;i++)

{

for(ii=i+1;ii<datacount;ii++)

{

if(idx[i]==-1||idx[ii]==-1)

continue;


if(compare(data,idx[i],idx[ii])>0)

{

int bak;


bak=idx[i];

idx[i]=idx[ii];

idx[ii]=bak;


goto restart;

}

}

}

}



// чтение с учетом фиктивных отрезков


int taperead_f(int *D,int *F,int *A,int *C,int *tape_logical,int tapeindex)

{

int value;

C[tape_logical[tapeindex]]++;

D[tape_logical[tapeindex]]--;


value=taperead(tape_logical[tapeindex]);

if(value==-1)

F[tape_logical[tapeindex]]--;


return value;

}


// запись на касету, работает с фиктивными отрекзами


void tapewrite_f(int*D,int *F,int *tape_logical,int tapeindex,int value)

{

D[tape_logical[tapeindex]]++;

if(value==-1)

{

F[tape_logical[tapeindex]]++;

}


{

tapewrite(tape_logical[tapeindex],value);

}

}


// D[] - количество отрезков на ленте (включая фиктивные)

// F[] - количество фиктивных отрезков

// A[] - длинна отрезка на ленте

// C[] - распределение текущее (сколько отрезков прочитано)

// n - касета результата, она же максимальное количесвтво касет для текущего распределния


// функция делает одно распределение. если во время него появилась пустая касета

// возвращаеться 1, и вообще возвращаеться количество путых касет


int cascadedistribution(field* data,int *D,int *F,int *A,int *C,int n,int *tape_logical,int tapecount)

{

int tapeindex;

int min;

int *tapebuf=malloc(sizeof(int)*tapecount);

int *tapeaccess=malloc(sizeof(int)*tapecount);

int ret = 0;


for(tapeindex=0;tapeindex<n;tapeindex++)

{

tapebuf[tape_logical[tapeindex]]=taperead_f(D,F,A,C,tape_logical,tapeindex);

tapeaccess[tape_logical[tapeindex]]=1;


if(D[tape_logical[tapeindex]]==0)

ret++;

}


{

loop:

min=-1;


// min примет другое значение только если есть еще блоки для сортировки.

// это означает что либо буфер не пуст, либо за эти проходы не считались все данные

// C[] < A[] (считанных отрезков меньше чем их длины)


// поиск минимального осуществляеться только в тех массивах где нет максимального числа

// прочитанных блоков


for(tapeindex=0;tapeindex<n;tapeindex++)

{

if(!tapeaccess[tape_logical[tapeindex]])

continue;


if(min==-1)

{

min=tapeindex;

continue;

}


if(compare(data,tapebuf[tape_logical[tapeindex]],tapebuf[tape_logical[min]])<0)

min=tapeindex;

}


// запись найденого елемента

if(min!=-1)

{

// записывую на ленту выхода значение минимального елемента

tapewrite_f(D,F,tape_logical,n,tapebuf[tape_logical[min]]);

// только если длинна считанного отрезка не больше его максимальной длинны

// читаю следующий отрезок.

// по идее требуеться проверить наличие елементов для чтение, но эта проверка

// автоматически проходит на наличие максимальной длинны (длинна отрезка не

// может превышать количство болков, она завязана на число Фибаначи)

if(C[tape_logical[min]]<A[tape_logical[min]])

{

tapebuf[tape_logical[min]]=taperead_f(D,F,A,C,tape_logical,min);

if(D[tape_logical[min]]==0)

ret++;

}else

tapeaccess[tape_logical[min]]=0;

goto loop;

}

}


free(tapebuf);

free(tapeaccess);


return ret;

}


// n-путевое силяние

// путевое слияние


// функция повторяет распределение пока нет пустой касеты

// если распределение завершилось 1


int cascadepathlink(field* data,int*D,int *F,int *A,int n,int *tape_logical,int tapecount)

{

// n = куда лить.

// n-1 - максимальное значение


int * C=malloc(sizeof(int)*tapecount);

//int i;

int ret=0;

int code=0;


while(1)

{

_memset(C,0,sizeof(int)*tapecount);

switch(cascadedistribution(data,D,F,A,C,n,tape_logical,tapecount))

{

case 0:

break; // goto looop

case 1:

goto exit;

default: //if(code>1)

ret=1;

goto exit;

}

}


exit:

free(C);

return ret;

}


// функция делает проход, пока не опустеет посделняя касета


void cascadepass(field* data,int *D,int *F,int* A,int *tape_logical,int tapecount)

{

int i;


for(i=tapecount-1;i>0;i--)

{

tapeinit(tape_logical[i]);

if(cascadepathlink(data,D,F,A,i,tape_logical,tapecount))

break;

}

}


#ifdef _DEBUG


#pragma comment(lib,"kernel32.lib")

#include <stdlib.h>

void __stdcall OutputDebugStringA(const char* lpOutputString);

void sprintf(char *, const char *, ...);


void tapesdump(field* data,int *D,int *F,int* A,int *tape_logical,int tapecount)

{

int casette;


tapesinit();


for(casette=0;casette<T;casette++)

{

int element;

char buf[1024];

sprintf(buf,"Casette %d (отрезков: %d, фиктивных: %d, длинна: %d)\n",casette,D[casette],F[casette],A[casette]);

OutputDebugStringA(buf);

for(element=0;element<D[casette];element++)

{

int value=taperead(casette);

sprintf(buf,"\t%d - '%s'(idx:%d)\n",element,value==-1?"":data[value],value);

OutputDebugStringA(buf);

if(div(element+1,A[casette]).rem==0)

OutputDebugStringA("\n");

}

}

}


#else


#define tapesdump(data,D,F,A,tape_logical,tapecount) (void)0

#endif


// первое распределение фибоначи


int fibonacheinit(int *f,int *tape_logical,int tapecount)

{

int i,total=0;


for(i=0;i<tapecount-1;i++)

{

f[tape_logical[i]]=1;

total+=f[tape_logical[i]];

}

return total;

}


// получение распределения фибоначи


int fibonachenext(int *f,int *tape_logical,int tapecount)

{

// 0 1 2 3 4 5


// physical


// 0 0 0 0 0 0

// 1 1 1 1 1 -

// - 1 2 3 4 5

// 15 14 12 9 5 -


// logical


// 0 0 0 0 0 0

// 1 1 1 1 1 -

// 5 4 3 2 1 -

// 15 14 12 9 5 -


int i,total=0;

int* fnew;


fnew=malloc(sizeof(int)*tapecount);

_memset(fnew,0,sizeof(int)*tapecount);


// здесь происходит обращение не к f[tape_logical[0]] поскольку

// сейчас касеты уже инвертированы

fnew[tape_logical[1]]=f[tape_logical[0]];

total=fnew[tape_logical[1]];


for(i=2;i<tapecount;i++)

{

fnew[tape_logical[i]]=fnew[tape_logical[i-1]]+f[tape_logical[i-1]];

total+=fnew[tape_logical[i]];

}


_memcpy(f,fnew,sizeof(int)*tapecount);


free(fnew);


return total;

}


// логичесвое инверсирование касет


void tapesinvert(int *tape_logical,int tapecount)

{

int i;


for(i=0;i<tapecount/2;i++)

{

int bak;


bak=tape_logical[i];

tape_logical[i]=tape_logical[tapecount-1-i];

tape_logical[tapecount-1-i]=bak;

}

}


// сброс логических касет


void tapesreset(int *tape_logical,int tape_count)

{

int i;

for(i=0;i<tape_count;i++)

tape_logical[i]=i;

}


int sort(field *data,int datasize,int *selectfieldsidx,int selectfieldscount,int orderfieldidx)

{

const int linecount = datasize/selectfieldscount;

// логическое устройство

int tape_logical[T];

// количество уровней распределения

int l = 0;

// количество отрезков на ленто протяжном устройстве

int D[T]={0};

// количество фиктивных отрезков

int F[T]={0};

int keyfieldnum=findinnumarray(selectfieldsidx,selectfieldscount,orderfieldidx);


tapescreate(1000);

tapesreset(tape_logical,T);


// спецальное распредлеение


{

int A[T]={0};

int offset=0;


// получаю конечное распределение фибоначи, к которому стремлюсь

int total=fibonacheinit(A,tape_logical,T);

l=1;

while(total<linecount)

{

total=fibonachenext(A,tape_logical,T);

tapesinvert(tape_logical,T);

l++;

}

for(offset=keyfieldnum;offset<datasize;offset+=selectfieldscount)

{

// ищу место куда можно положить данные

{

int i;

for(i=0;i<T;i++)

{

if(D[tape_logical[i]]<A[tape_logical[i]])

{

tapewrite_f(D,F,tape_logical,i,offset);

break;

}

}

}

}


// после распределения нужно забить числа фиктивных отрезков

// в соответствии с числами фибоначи, так же привести D (кол

// ичество отрезков на лентах включая фиктивные отрезки) в

// соответсвтии с последним распределением


{

int i,offset;

for(offset=linecount;offset<total;offset++)

{

for(i=0;i<T;i++)

{

if(D[tape_logical[i]]<A[tape_logical[i]])

{

tapewrite_f(D,F,tape_logical,i,-1);

}

}

}

}

}


// каскадное слияние


{

// требуеться числа для распределения фибонаци, начальние значения отрезков по

// лентам.

int A[T]={0};

fibonacheinit(A,tape_logical,T);


while(l--)

{

tapesdump(data,D,F,A,tape_logical,T);


tapesinit();

cascadepass(data,D,F,A,tape_logical,T);

fibonachenext(A,tape_logical,T);

tapesinvert(tape_logical,T);


tapesdump(data,D,F,A,tape_logical,T);

}

}


// сортировка данных


{

int index=0;

field *datanew=malloc(sizeof(field)*datasize);


tapesinit();

while(index<linecount)

{

int i;

int idx=taperead(tape_logical[0]);


for(i=0;i<selectfieldscount;i++)

_strcpy(datanew[index*selectfieldscount+i],data[idx-keyfieldnum+i]);

index++;

}

_memcpy(data,datanew,sizeof(field)*datasize);

free(datanew);

}


tapesclose();

return 0;

}

stdio.h

typedef void FILE;

typedef unsigned int size_t;


#define EOF -1


// CRT {


int feof( FILE *stream );

int fgetc( FILE *stream );

FILE *fopen( const char *filename, const char *mode );

size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );

int fclose( FILE *stream );

size_t fread( void *buffer, size_t size, size_t count, FILE *stream );


int printf( const char *format , ... );

int getc( FILE *stream );

int getchar();


// } CRT


// Addin {


// получает строчку со стандартного устройста ввода

char *_gets( char *buffer,int buffermax);

// записывает строчку оканчивующуся нулем в файл

size_t fwritestring(FILE*,const char*);


// } Addin

stdio.c

#include "stdio.h"

#include "stdlib.h"


size_t fwritestring(FILE* file,const char*p)

{

return fwrite(p,sizeof(char),_strlen(p),file);

}


char *_gets( char *buffer,int buffermax)

{

int i;


buffermax--;


while((i=getchar())!=EOF)

{

if(i==0x0a)

break;

*buffer++=i;

if(--buffermax==0)

break;

}

*buffer=0;

return buffer;

}

stdlib.h

#include "types.h"


// CRT {


void * malloc(unsigned);

void free(void*);

double atof(const char*);


// } CRT


// 0 - different ; 1 - eq

int _streq(const char*,const char*);

int _strncmp(const char* i,const char* ii,int count);

// определяет строчку по типу, если это строчка в ковычках - текст.

int _stringformatcmp(const char*,const char*);

int _strcmp(const char *, const char *);

int _strcpy(char*,const char*);

int _strlen(const char*);

void * _memcpy( void *dest, const void *src, int count );

void * _memset( void *dest, int c, int count );

// ищет в массиве flds поля what, возвращает его индекс

int findinarray(fieldname * flds,const char* what);

int findinnumarray(int * flds,int fldscount,int what);

stdlib.c

#include "stdlib.h"


int _streq(const char* i,const char* ii)

{

while(*i++==*ii++)

{

if(*i==0&&*ii==0)

return 1;

}

return 0;

}


#define ISNUMBER(x) (x>='0'&&x<='9'||x==','||x=='.'||x=='-')


// орпеделяет есть ли буквы во входной строчке


int haveletters(const char* i)

{

while(*i!=0)

{

if(!ISNUMBER(*i))

return 1;

}

return 0;

}


int _stringformatcmp(const char* i,const char* ii)

{

if(*i=='"'&&*ii=='"')

return _strcmp(i,ii);

if(*i=='"')

return _strncmp(i+1,ii,_strlen(i)-2);

if(*ii=='"')

return _strncmp(i,ii+1,_strlen(ii)-2);

if(haveletters(i)||haveletters(ii))

return _strcmp(i,ii);

return atof(i)<atof(ii);

}


int _strcmp(const char* i,const char* ii)

{

while(*i==*ii)

{

if(*i==0) // если ровна первая ровна и вторая

return 0;

ii++;

i++;

}

return *i<*ii?-1:1;

}


int _strncmp(const char* i,const char* ii,int count)

{

while(*i==*ii&&count--)

{

if(*i==0) // если ровна первая ровна и вторая

return 0;

ii++;

i++;

}

return count==0?0:*i<*ii?-1:1;

}


int _strcpy(char* p,const char* pp)

{

while(*p++=*pp++)

;

return 1;

}


int _strlen(const char* p)

{

int len=0;

while(*p++)

len++;

return len;

}


int findinnumarray(int * flds,int fldscount,int what)

{

int i;

for(i=0;i<fldscount;i++)

{

if(flds[i]==what)

return i;

}

return -1;

}


int findinarray(fieldname * flds,const char* what)

{

int count=0;

while(!_streq(*flds++,what))

count++;

return count;

}


void * _memcpy( void *dest, const void *src, int count )

{

unsigned char *d=(unsigned char *)dest,*s=(unsigned char *)src;

while(count--)

*d++=*s++;

return 0;

}


void * _memset( void *dest, int c, int count )

{

unsigned char *d=(unsigned char *)dest;

while(count--)

*d++=c;

return 0;

}

Stage.c

#include "types.h"

#include "parse.h"

#include "select.h"

#include "sort.h"

#include "show.h"

#include "error.h"

#include "stdio.h"

#include "stdlib.h"


int main()

{

fieldname selectfields[32]={0}; // имена полей по которым идет запрос

int selectfieldsidx[32]={0}; // индексы полей по кторомыи идет запрос (номера по порядку файловых заголовков)

int selectfieldscount;

fieldname orderfield={0}; // имя поля по которому сортируют

// его индекс (номер поля в базе из которой идет запрос, он совпадет

// с одним из индексом из selectfieldsidx.

int orderfieldidx;

// имена файлов-базданных из которых будет браться запрос.

tablename tbls[32]={0};


const int datamaxsize=32768;

int datasize=0;

field *data=(field*)malloc(sizeof(field)*datamaxsize);


//char cmdline[1024]="select header2,header3,header1 from base.csv,base3.csv order by header3";

char cmdline[1024]="select * from material_w1251.txt order by UNIT";

char outputname[260]="baseout.csv";


printf("enter select:\n");

_gets(cmdline,sizeof(cmdline));

printf("enter output file:\n");

_gets(outputname,sizeof(outputname));


if(!parse(selectfields,sizeof(selectfields)/sizeof(fieldname),tbls,sizeof(tbls)/sizeof(tablename),&orderfield,cmdline))

goto error;


if(!normalizeparams(selectfields,&orderfield,tbls,selectfieldsidx,&selectfieldscount,&orderfieldidx))

goto error;


if((datasize=select(selectfieldsidx,selectfieldscount,tbls,data,datamaxsize))==-1)

goto error;


if(sort(data,datasize,selectfieldsidx,selectfieldscount,orderfieldidx))

goto error;


if(!show(data,selectfieldsidx,selectfieldscount,orderfieldidx,outputname))

goto error;


free(data);

return 0;

error:

free(data);

printf("Stage fatal error: '%s'\n",geterror());

return 1;

}


// select * from adfas order by 1,2


/*

I parse разберает строчку

II load грузит указанные поля

III sort сортирует

IV выводит


fields

table

orders

*/


Hosted by uCoz